package BandB.Tool.GPhoneManager.FileExplorer;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.Timer;
import java.util.TimerTask;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import BandB.Tool.GPhoneManager.MediaListener;
import BandB.Tool.GPhoneManager.R;
import BandB.Tool.GPhoneManager.FileExplorer.Installer.Installer;
import BandB.Tool.GPhoneManager.FileExplorer.Util.Utilities;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.view.View.OnKeyListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText; //import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;

public class FileExplorer extends Activity {

	public static final String ROOT_DIRECTORY = "root_directory";
	protected static final int OP_NONE = -1;
	protected static final int MENU_COPY = 0;
	protected static final int MENU_CUT = 1;
	protected static final int MENU_PASTE = 2;
	protected static final int MENU_DELETE = 3;
	protected static final int MENU_RENAME = 4;
	protected static final int MENU_NEW_FOLDER = 5;
	protected static final int MENU_CANCEL = 6;

	private static final int NEW_FOLDER_DIALOG = 0;
	private static final int RENAME_DIALOG = 1;
	private static final int ZIP_FILE = 2;
	// private static final int UNZIP_FILE = 3;

	private File currentDirectory;
	// private File zipSourceFile = null;
	private ArrayList<String> zipSourceDirs = null;
	private int currentOp = OP_NONE;

	File sourceFile = null;
	File destFile = null;
	Thread workingThread = null;
	MenuItem menuNewFolder, menuPaste;
	ListView listView;
	Button selectedMode;
	private ProgressDialog pDialog;

	public static final int MODE_SINGLE = 0;
	public static final int MODE_MULTIPLE = 1;
	protected static final int MSG_UNZIP_DONE = 11;
	private static final int MSG_REFRESH_SPACE_INFO = 64;

	public static int currentMode = MODE_SINGLE;

	private String TAG = FileExplorer.class.getSimpleName();

	private TextView txtTotalSize;
	private TextView txtLeftSize;
	private TextView noFile;
	private LinearLayout navigationBar;
	private EditText searchBox;
	private Button searchBtn;
	private String mTotalSize;
	private String mLeftSize;

	public static File root;

	private Runnable mGoogleAdRefreshRunnable;
	private Timer swapTimer;

	@Override
	protected void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		setContentView(R.layout.file_explorer);
		txtTotalSize = (TextView) findViewById(R.id.txtTotalSize);
		txtLeftSize = (TextView) findViewById(R.id.txtLeftSize);
		noFile = (TextView) findViewById(R.id.no_file);
		noFile.setVisibility(View.GONE);

		listView = (ListView) findViewById(R.id.lstFiles);
		listView.setOnCreateContextMenuListener(onCreateContextMenuListener);
		listView.setOnItemClickListener(listItemClicked);
		listView.setEmptyView(noFile);

		selectedMode = (Button) findViewById(R.id.select_mode);
		selectedMode.setOnClickListener(modeClickListener);
		setSelectModeButton();

		searchBox = (EditText) findViewById(R.id.search_box);
		searchBox.setOnKeyListener(searchOnKeyListener);

		searchBtn = (Button) findViewById(R.id.search_btn);
		searchBtn.setOnClickListener(searchClickListener);

		navigationBar = (LinearLayout) findViewById(R.id.navigation_bar);
		if (!MediaListener.isSDCardAvailable()) {
			Toast.makeText(this, "SDCard does not exist, please check.",
					Toast.LENGTH_SHORT).show();
			return;
		}
		root = Environment.getExternalStorageDirectory();

		if (getIntent().getStringExtra(ROOT_DIRECTORY) != null) {
			currentDirectory = new File(getIntent().getStringExtra(
					ROOT_DIRECTORY));
		} else {
			currentDirectory = root;
		}
		gotoDirectory(currentDirectory);
		refreshSpaceInfo();

		// final GoogleAdView adView = (GoogleAdView) findViewById(R.id.adview);
		// final String[] keyWord = new String[] {
		// "term life insurance quote,austin dwi,car insurance quotes",
		// "Austin Texas dwi lawyers,android application" };
		/*
		 * final AdSenseSpec adSenseSpec = new AdSenseSpec(
		 * "ca-mb-app-pub-1022548373139673") // Specify client
		 * .setCompanyName("best") // Set company name. (Required)
		 * .setAppName("Tools") // Set application name. (Required) //
		 * .setKeywords(
		 * "term life insurance quote,austin dwi,car insurance quotes,Austin Texas dwi lawyers,android application"
		 * ) // // Specify keywords. //
		 * .setKeywords("term life insurance quote,austin dwi") // // Specify
		 * keywords. .setChannel("4038584105") // Set channel ID.
		 * .setAdTestEnabled(false);
		 * 
		 * // adView.showAds(adSenseSpec);
		 * 
		 * this.mGoogleAdRefreshRunnable = new Runnable() {
		 * 
		 * @Override public void run() { if (keyWordIndex > 1) { keyWordIndex =
		 * 0; } adSenseSpec.setKeywords(keyWord[keyWordIndex]); //
		 * adView.showAds(adSenseSpec); keyWordIndex++; } };
		 * 
		 * requestAdParameters();
		 */
	}

	public synchronized void requestAdParameters() {

		this.swapTimer = new Timer();
		this.swapTimer.schedule(new TimerTask() {

			@Override
			public void run() {
				Thread mDownloadThread = new Thread(mGoogleAdRefreshRunnable);
				mDownloadThread.start();
			}

		}, 0, 45 * 1000);
	}

	private void setSelectModeButton() {
		if (currentMode == MODE_MULTIPLE) {
			selectedMode.setBackgroundResource(R.drawable.multi_list);
		} else if (currentMode == MODE_SINGLE) {
			selectedMode.setBackgroundResource(R.drawable.signal_list);
		}
	}

	OnKeyListener searchOnKeyListener = new OnKeyListener() {

		@Override
		public boolean onKey(View v, int keyCode, KeyEvent event) {
			if (event.getAction() == KeyEvent.ACTION_UP) {
				if (keyCode == KeyEvent.KEYCODE_ENTER) {
					searchBtn.performClick();
				}
			}
			return false;
		}

	};

	private OnClickListener searchClickListener = new OnClickListener() {

		@Override
		public void onClick(View v) {
			String keyword = searchBox.getText().toString();
			if (TextUtils.isEmpty(keyword)) {
				return;
			}
			startSearch(keyword);
		}

	};

	private FileLauncher fileLauncher = FileLauncher.getInstance(this);
	private boolean localeChanged;

	private void startSearch(String keyword) {
		fileLauncher.loadFiles(true, this, localeChanged, root, keyword,
				currentMode);
		FileAdapter fileAdapter = fileLauncher.getFilesAdapter();
		fileAdapter.setCurrentMode(MODE_SINGLE);
		listView.setAdapter(fileAdapter);
	}

	private OnClickListener modeClickListener = new OnClickListener() {

		@Override
		public void onClick(View v) {
			if (currentMode == MODE_MULTIPLE) {
				currentMode = MODE_SINGLE;
			} else if (currentMode == MODE_SINGLE) {
				currentMode = MODE_MULTIPLE;
			}
			((FileAdapter) listView.getAdapter()).setCurrentMode(currentMode);
			setSelectModeButton();
		}

	};

	private OnItemClickListener listItemClicked = new OnItemClickListener() {

		@Override
		public void onItemClick(AdapterView<?> arg0, View view, int position,
				long id) {
			FileItem fileItem = (FileItem) view.getTag();
			Log.i(TAG, "opening file " + fileItem.file.getPath());
			gotoDirectory(fileItem.file);
		}

	};

	@Override
	public boolean onContextItemSelected(MenuItem item) {

		AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item
				.getMenuInfo();
		final FileItem fileItem = (FileItem) menuInfo.targetView.getTag();
		switch (item.getItemId()) {
		case MENU_UNZIP:
			pDialog = new ProgressDialog(this);
			pDialog.setTitle("waiting");
			pDialog.setMessage("Unzipping...");
			pDialog.show();
			new Thread(new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					ZipHelper.zipExtracting(fileItem.file.getParent(),
							fileItem.file.getPath());

					handler.sendEmptyMessage(MSG_UNZIP_DONE);
				}
			}).start();
			// pDialog.dismiss();
			// gotoDirectory(currentDirectory);
			break;
		case MENU_COPY:
			// break;
		case MENU_CUT:
			currentOp = item.getItemId();
			sourceFile = fileItem.file;
			break;
		case MENU_DELETE:
			deleteFile(fileItem.file);
			break;
		case MENU_PASTE:
			if (currentMode == MODE_SINGLE) {
				pasteFile(fileItem.file, sourceFile);
			} else if (currentMode == MODE_MULTIPLE) {
				for (int i = 0; i < checkedFile.size(); i++) {
					pasteFile(fileItem.file, checkedFile.get(i).file);
				}
			}
			break;
		case MENU_CANCEL:
			sourceFile = null;
			currentOp = OP_NONE;
			break;
		case MENU_NEW_FOLDER:
			currentOp = MENU_NEW_FOLDER;
			showDialog(NEW_FOLDER_DIALOG);
			break;
		case MENU_RENAME:
			sourceFile = fileItem.file;
			currentOp = MENU_RENAME;
			showDialog(RENAME_DIALOG);
			break;
		default:
			break;
		}
		return super.onContextItemSelected(item);
	}

	private void deleteFile(final File file) {
		new Thread(new Runnable() {
			@Override
			public void run() {

				final String message = file.getName();
				try {
					Utilities.fileDelete(file);
					Toast.makeText(getBaseContext(),
							message + " Succeed to delete files.",
							Toast.LENGTH_LONG).show();
					// if current mode is multiple selected mode,
					// we remove file from list
					if (currentMode == MODE_MULTIPLE) {
						checkedFile.remove(file);
					}
					listView.post(new Runnable() {
						@Override
						public void run() {
							// Toast.makeText(getBaseContext(),
							// message + " delete completed.",
							// Toast.LENGTH_LONG).show();
							gotoDirectory(currentDirectory);
						}
					});
				} catch (Exception e) {

					listView.post(new Runnable() {
						@Override
						public void run() {
							currentOp = OP_NONE;
							Toast.makeText(getBaseContext(),
									message + " delete failed.",
									Toast.LENGTH_LONG).show();
						}
					});
				}

			}
		}).start();
	}

	private Stack<Button> accessStack = new Stack<Button>();

	// private boolean isRootDirectory;

	private void gotoDirectory(File directory) {
		currentDirectory = directory;
		// setTitle(directory.getPath());
		if (currentDirectory.getPath().equalsIgnoreCase("/")) {
			// isRootDirectory = true;
		} else {
			// isRootDirectory = false;
		}
		if (directory.isDirectory()) {
			listView.setAdapter(new FileAdapter(this, Utilities
					.listFileItem(directory), currentMode));

		} else if (directory.isFile()) {
			Utilities.tryOpenFile(this, directory);
		}
		// 生成地址栏
		buildNavigationBarFromFile(directory);

	}

	private void addOnebuttonToNavigationBar(File file) {
		Button currentFolder = new Button(this);
		if (file.getPath().equalsIgnoreCase("/")) {
			currentFolder.setText("root");
		} else {
			currentFolder.setText(file.getName());
		}
		// currentFolder.setBackgroundColor(0Xe9e9e9);
		currentFolder.setTag(file);
		currentFolder.setBackgroundResource(R.drawable.file_arrow);
		currentFolder.setLayoutParams(new LinearLayout.LayoutParams(
				LinearLayout.LayoutParams.WRAP_CONTENT,
				LinearLayout.LayoutParams.FILL_PARENT));
		currentFolder.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				gotoDirectory((File) v.getTag());
			}

		});

		LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
				LinearLayout.LayoutParams.WRAP_CONTENT,
				LinearLayout.LayoutParams.WRAP_CONTENT);

		navigationBar.addView(currentFolder, params);
		accessStack.push(currentFolder);

	}

	/*
	 * 返回上一级目录，同时更新地址栏
	 */
	private void removeOneButtonFromNavigationBar() {
		if (!accessStack.isEmpty()) {
			Button topDirectory = accessStack.pop();
			navigationBar.removeView(topDirectory);
		}
	}

	private void removeAllButtonFromNavitationBar() {
		while (!accessStack.isEmpty()) {
			removeOneButtonFromNavigationBar();
		}
	}

	/*
	 * 跳转到任一路径，同时更新地址栏
	 */
	private void buildNavigationBarFromFile(File file) {
		if (file.isFile()) {
			return;
		}
		removeAllButtonFromNavitationBar();
		Stack<File> fileStack = new Stack<File>();
		File current = file;
		// 从传进来的路径一直往前回溯，直到root节点，并按路径顺序从新构造地址栏
		do {
			fileStack.push(current);
			current = current.getParentFile();
		} while (!fileStack.peek().equals(root));

		while (!fileStack.isEmpty()) {
			addOnebuttonToNavigationBar(fileStack.pop());
		}
		if (null != accessStack.peek()) {
			accessStack.peek().setSelected(true);
		}
	}

	private static final int MSG_ZIP_DONE = 0;
	protected static final int MENU_UNZIP = 100;

	Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			switch (msg.what) {
			case MSG_REFRESH_SPACE_INFO:
				if (!TextUtils.isEmpty(mTotalSize)
						|| !TextUtils.isEmpty(mLeftSize)) {
					long totalSize = Long.parseLong(mTotalSize);
					StringBuffer sb = new StringBuffer(20);
					StringBuffer leftBuffer = new StringBuffer(20);
					String total = String.valueOf(totalSize >> 10);
					sb.append(total).append(" MB total");
					txtTotalSize.setText(sb.toString());
					long leftSize = Long.parseLong(mLeftSize);
					String left = String.valueOf(leftSize >> 10);
					leftBuffer.append(left).append(" MB available");
					txtLeftSize.setText(leftBuffer.toString());
				} else {
					Log.e(TAG, "Fetch space info error.");
				}
				break;
			case MSG_ZIP_DONE:
				if (pDialog != null) {
					pDialog.dismiss();
				}
				gotoDirectory(currentDirectory);
				break;
			case MSG_UNZIP_DONE:
				if (pDialog != null) {
					pDialog.dismiss();
				}
				if (currentDirectory.isDirectory()) {
					gotoDirectory(currentDirectory);
				} else {
					gotoDirectory(new File(currentDirectory.getParent()));
				}
				break;
			default:
				break;
			}
			super.handleMessage(msg);
		}
	};

	@Override
	protected Dialog onCreateDialog(int id) {

		switch (id) {
		case ZIP_FILE:
			LayoutInflater inflater = LayoutInflater.from(this);
			final View txtEntry = inflater.inflate(
					R.layout.alert_dialog_text_entry, null);
			return new AlertDialog.Builder(this).setTitle(
					R.string.input_new_name).setView(txtEntry)
					.setPositiveButton(R.string.ok,
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {
									EditText newNameEdit = (EditText) txtEntry
											.findViewById(R.id.newName);
									final String s = newNameEdit.getText()
											.toString();
									pDialog = new ProgressDialog(
											FileExplorer.this);
									pDialog.setTitle("waiting");
									pDialog.setMessage("zipping...");
									pDialog.show();
									new Thread(new Runnable() {
										@Override
										public void run() {
											// TODO Auto-generated method stub
											if (currentDirectory.isDirectory()) {
												ZipHelper.zip(zipSourceDirs,
														currentDirectory + "/"
																+ s + ".zip",
														false);
											} else {
												String temp = currentDirectory
														.getParent();
												ZipHelper
														.zip(
																zipSourceDirs,
																temp
																		+ "/"
																		+ s
																		+ ".zip",
																false);
											}

											handler
													.sendEmptyMessage(MSG_ZIP_DONE);
										}
									}).start();

								}
							}).setNegativeButton(R.string.cancel,
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {
									/* User clicked cancel so do some stuff */
									currentOp = OP_NONE;
								}
							}).create();
		case RENAME_DIALOG:
			LayoutInflater factory = LayoutInflater.from(this);
			final View textEntryView = factory.inflate(
					R.layout.alert_dialog_text_entry, null);
			return new AlertDialog.Builder(this).setTitle(
					R.string.input_new_name).setView(textEntryView)
					.setPositiveButton(R.string.ok,
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {

									/* User clicked OK so do some stuff */
									EditText newNameEdit = (EditText) textEntryView
											.findViewById(R.id.newName);
									String s = newNameEdit.getText().toString();
									try {
										File f = new File(sourceFile
												.getParentFile(), s);
										Utilities.fileRename(sourceFile, f);
										currentOp = OP_NONE;
										Toast.makeText(
												FileExplorer.this,
												sourceFile.getName()
														+ " rename to " + s
														+ " completed.",
												Toast.LENGTH_LONG).show();
										gotoDirectory(currentDirectory);
									} catch (Exception e) {

										currentOp = OP_NONE;
										Toast.makeText(
												FileExplorer.this,
												sourceFile.getName()
														+ " rename to " + s
														+ " failed.",
												Toast.LENGTH_LONG).show();
									}

								}
							}).setNegativeButton(R.string.cancel,
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {
									/* User clicked cancel so do some stuff */
									currentOp = OP_NONE;
								}
							}).create();
		case NEW_FOLDER_DIALOG:
			factory = LayoutInflater.from(this);
			final View textEntryView2 = factory.inflate(
					R.layout.alert_dialog_text_entry, null);
			return new AlertDialog.Builder(this).setTitle(
					R.string.input_new_name).setView(textEntryView2)
					.setPositiveButton(R.string.ok,
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {

									/* User clicked OK so do some stuff */
									EditText newFolderEdit = (EditText) textEntryView2
											.findViewById(R.id.newName);
									String s = newFolderEdit.getText()
											.toString();
									try {
										File f = new File(currentDirectory, s);
										Utilities.newFolder(f);
										currentOp = OP_NONE;
										Toast.makeText(
												FileExplorer.this,
												"Create folder " + s
														+ " completed.",
												Toast.LENGTH_LONG).show();
										gotoDirectory(currentDirectory);
									} catch (Exception e) {

										currentOp = OP_NONE;
										Toast.makeText(
												FileExplorer.this,
												"Create folder \"" + s
														+ "\" failed.",
												Toast.LENGTH_LONG).show();
									}

								}
							}).setNegativeButton(R.string.cancel,
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {
									/* User clicked cancel so do some stuff */
									currentOp = OP_NONE;
								}
							}).create();
		default:
			break;
		}

		return super.onCreateDialog(id);
	}

	@Override
	protected void onPrepareDialog(int id, Dialog dialog) {

		switch (id) {
		case RENAME_DIALOG:
			EditText newFolderEdit = (EditText) dialog
					.findViewById(R.id.newName);
			newFolderEdit.setText(sourceFile.getName());
			break;
		case NEW_FOLDER_DIALOG:

			break;
		default:
			break;
		}
		super.onPrepareDialog(id, dialog);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.file_explorer_menu, menu);
		return super.onCreateOptionsMenu(menu);
	}

	private void startInstaller() {
		Intent intent = new Intent(this, Installer.class);
		intent.setAction(Intent.ACTION_VIEW);
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		startActivity(intent);
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {

		if (currentMode == MODE_SINGLE) {
			menu.setGroupVisible(R.id.single_group, true);
			menu.setGroupVisible(R.id.multiple_group, false);
		} else if (currentMode == MODE_MULTIPLE) {
			menu.setGroupVisible(R.id.multiple_group, true);
			menu.setGroupVisible(R.id.single_group, false);
		}

		return super.onPrepareOptionsMenu(menu);
	}

	private void pasteFile(File dest, final File source) {

		destFile = new File(dest, source.getName());
		if (dest.equals(source)) {
			Log.i("pasteFile", "invalid operation, ignore");
			Toast.makeText(this, "Invalid operation, ignore your request.",
					Toast.LENGTH_SHORT).show();
			return;
		} else if (source.getParentFile().equals(source)) {
			Toast.makeText(this, "The same file, ignore your request.",
					Toast.LENGTH_SHORT).show();
			return;
		} else {
			Log.i("pasteFile", "begin");
		}
		Log.i("pasteFile", "dest:" + dest);
		Log.i("pasteFile", "source:" + source);

		new Thread(new Runnable() {

			@Override
			public void run() {
				final String message = source.getName()
						+ (currentOp == MENU_COPY ? " copy" : " cut");
				Log.i("operation", message);

				try {
					if (source.isDirectory()) {
						destFile.mkdir();
					}
					if (currentOp == MENU_COPY) {
						Utilities.fileCopy(source, destFile);
					} else if (currentOp == MENU_CUT) {
						Utilities.fileCut(source, destFile);
						if (currentMode == MODE_SINGLE) {
							currentOp = OP_NONE;
						} else if (currentMode == MODE_MULTIPLE) {
							checkedFile.remove(source);
							if (checkedFile.size() == 0) {
								currentOp = OP_NONE;
							}
						}

					}
					listView.post(new Runnable() {
						@Override
						public void run() {
							Toast.makeText(getBaseContext(),
									message + " completed.", Toast.LENGTH_LONG)
									.show();
							gotoDirectory(currentDirectory);
						}
					});
				} catch (Exception e) {

					listView.post(new Runnable() {
						@Override
						public void run() {
							currentOp = OP_NONE;
							Toast.makeText(getBaseContext(),
									message + " failed.", Toast.LENGTH_LONG)
									.show();
						}
					});
				}

			}
		}).start();

	}

	private List<FileItem> checkedFile = new ArrayList<FileItem>();

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {
		case R.id.menu_new_folder:
			currentOp = MENU_NEW_FOLDER;
			showDialog(NEW_FOLDER_DIALOG);
			break;
		case MENU_PASTE:
			pasteFile(currentDirectory, sourceFile);
			break;
		case R.id.menu_installer:
			startInstaller();
			break;
		case R.id.menu_item_zip:
			checkedFile = ((FileAdapter) listView.getAdapter()).getCheckFile();
			int size = checkedFile.size();
			if (size == 0) {
				currentOp = OP_NONE;
				Toast.makeText(this, R.string.no_file_selected,
						Toast.LENGTH_LONG).show();
			} else {
				zipSourceDirs = new ArrayList<String>();
				for (int i = 0; i < size; i++) {
					File file = checkedFile.get(i).file;
					// if (file.isDirectory()) {
					zipSourceDirs.add(file.getPath());
					// }
				}
				showDialog(ZIP_FILE);
			}

			break;
		case R.id.menu_copy_selected:
			checkedFile = ((FileAdapter) listView.getAdapter()).getCheckFile();
			if (checkedFile.size() == 0) {
				currentOp = OP_NONE;
				Toast.makeText(this, R.string.no_file_selected,
						Toast.LENGTH_LONG).show();
			} else {
				currentOp = MENU_COPY;
			}
			break;
		case R.id.menu_cut_selected:
			checkedFile = ((FileAdapter) listView.getAdapter()).getCheckFile();
			if (checkedFile.size() == 0) {
				currentOp = OP_NONE;
				Toast.makeText(this, R.string.no_file_selected,
						Toast.LENGTH_LONG).show();
			} else {
				currentOp = MENU_CUT;
			}
			break;
		case R.id.menu_delete_selected:
			checkedFile = ((FileAdapter) listView.getAdapter()).getCheckFile();
			if (checkedFile.size() == 0) {
				currentOp = OP_NONE;
				Toast.makeText(this, R.string.no_file_selected,
						Toast.LENGTH_LONG).show();
			} else {
				for (int i = 0; i < checkedFile.size(); i++) {
					deleteFile(checkedFile.get(i).file);
				}
			}
			break;

		}
		return super.onOptionsItemSelected(item);
	}

	OnCreateContextMenuListener onCreateContextMenuListener = new OnCreateContextMenuListener() {

		@Override
		public void onCreateContextMenu(ContextMenu menu, View v,
				ContextMenuInfo menuInfo) {
			FileItem fileItem = (FileItem) ((AdapterContextMenuInfo) menuInfo).targetView
					.getTag();

			menu.setHeaderTitle("Select operation for "
					+ fileItem.file.getName());
			menu.add(0, MENU_COPY, 0, R.string.copy);
			menu.add(0, MENU_CUT, 1, R.string.cut);
			MenuItem pastItem = menu.add(0, MENU_PASTE, 2, R.string.paste);
			if ((currentOp == MENU_COPY || currentOp == MENU_CUT)
					&& fileItem.file.isDirectory()) {
				pastItem.setEnabled(true);
			} else {
				pastItem.setEnabled(false);
			}
			menu.add(0, MENU_RENAME, 3, R.string.rename);
			menu.add(0, MENU_DELETE, 4, R.string.delete);
			menu.add(0, MENU_CANCEL, 5, R.string.cancel);
			MenuItem unzipItem = menu.add(0, MENU_UNZIP, 6, "Unzip");
			if (isZipFile(fileItem.file)) {
				unzipItem.setEnabled(true);
			} else {
				unzipItem.setEnabled(false);
			}
		}

	};

	private boolean isZipFile(File file) {
		boolean isApkFile = false;
		String fileName = file.getName();
		Log.e("BackManager", "file name: " + fileName);
		try {
			String fileSuffix = fileName.substring(fileName.lastIndexOf("."),
					fileName.length());
			Log.i(TAG, "current file suffix=" + fileSuffix);
			if (fileSuffix.toLowerCase().equalsIgnoreCase(".zip")) {
				isApkFile = true;
			}
		} catch (Exception e) {
			return false;
		}

		return isApkFile;
	}

	private void refreshSpaceInfo() {
		try {
			String cmd = "df";
			Process process;
			Runtime runtime = Runtime.getRuntime();
			process = runtime.exec(cmd);
			InputStream is = process.getInputStream();
			InputStreamReader isr = new InputStreamReader(is);
			BufferedReader br = new BufferedReader(isr);
			String line = br.readLine();
			StringBuffer sb = new StringBuffer(1024);
			while (null != line) {
				sb.append(line);
				line = br.readLine();
			}
			String cmdResult = sb.toString();
			Pattern sdcardPattern = Pattern
					.compile("/sdcard: (\\d*)K[\\s\\S]*?(\\d*)K[\\s\\S]*?(\\d*)K");
			Matcher matcher = sdcardPattern.matcher(cmdResult);
			if (matcher.find()) {
				matcher.group();
				mTotalSize = matcher.group(1);
				mLeftSize = matcher.group(3);
				handler.sendEmptyMessage(MSG_REFRESH_SPACE_INFO);
			} else {
				Log.i(TAG, "No match found.");
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {

		if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
			if (currentDirectory.equals(root)) {
				new AlertDialog.Builder(this).setTitle(R.string.warning)
						.setMessage(R.string.root_file_warning)
						.setPositiveButton(R.string.yes,
								new DialogInterface.OnClickListener() {

									@Override
									public void onClick(DialogInterface dialog,
											int which) {
										finish();
									}

								}).setNegativeButton(R.string.no,
								new DialogInterface.OnClickListener() {

									@Override
									public void onClick(DialogInterface dialog,
											int which) {

									}

								}).show();
			} else {
				gotoDirectory(currentDirectory.getParentFile());
			}
			return true;
		}

		return super.onKeyUp(keyCode, event);
	}

}
